/* 
 * File:   common.h
 * Author: faraj
 *
 * Created on August 31, 2009, 12:15 AM
 */

#include "CFile.h"
#include "List.h"


#ifndef _COMMON_H
#define	_COMMON_H

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <sys/uio.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/un.h>
#include <signal.h>
#include <pthread.h>
#include <sys/time.h>
#include <vector>
#include <sys/stat.h>
#include <dirent.h>

using namespace std;


#include "List.h"

#define	MAXLINE	4096
#define	LISTENQ	1024
#define	SA struct sockaddr

bool 
getFileExcistance(string path)
{
    struct stat st;
    return (stat(path.c_str(),&st) == 0);
}

bool 
createDir(string path)
{
        return (mkdir(path.c_str(),0777) == 0);               
}


int 
getFileSize(string path)
{
    struct stat64 st; 
    int err = stat64(path.c_str(), &st ); 
    if (0 != err) return 0; 
    return st.st_size; 
}


void 
Tokenize(const string& str,
                      vector<string>& tokens,
                      const string& delimiters = " ")
{
    // Skip delimiters at beginning.
    string::size_type lastPos = str.find_first_not_of(delimiters, 0);
    // Find first "non-delimiter".
    string::size_type pos     = str.find_first_of(delimiters, lastPos);

    while (string::npos != pos || string::npos != lastPos)
    {
        // Found a token, add it to the vector.
        tokens.push_back(str.substr(lastPos, pos - lastPos));
        // Skip delimiters.  Note the "not_of"
        lastPos = str.find_first_not_of(delimiters, pos);
        // Find next "non-delimiter"
        pos = str.find_first_of(delimiters, lastPos);
    }
}


bool 
err_sys(string value)
{
    printf("%s\n",value.c_str());
    return false;
}

int
Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
       struct timeval *timeout)
{
	int n;

	if ( (n = select(nfds, readfds, writefds, exceptfds, timeout)) < 0)
            return -999;
	return(n);		/* can return 0 on timeout */
}

ssize_t 
readn(int fd, void *vptr, size_t n)
{
    size_t nleft;
    ssize_t nread;

    char *ptr;
    ptr = (char*)vptr;
    nleft = n; 
    while (nleft > 0) 
    {
         if ( (nread = read(fd, ptr, nleft))<0) 
         {
             if (errno == EINTR)
                nread = 0;
             else
                return(-1);
         } 
         else if (nread == 0)
             break;
         nleft -= nread;
         ptr   += nread;
    }
    return(n - nleft);
}

ssize_t 
Readn(int fd, void *ptr, size_t nbytes)
{
    ssize_t n;
    if ( (n = readn(fd, ptr, nbytes)) < 0)
    {
        err_sys("readn error");
        return -1; 
    }
    return(n);
}


ssize_t 
writen(int fd, const void *vptr, size_t n)
{
    size_t nleft;
    ssize_t nwritten;
    const char *ptr;
    
    ptr = (char*)vptr;

    nleft = n;
    while (nleft > 0) 
    {
        if ( (nwritten = write(fd, ptr, nleft)) <= 0) 
        {
            if (errno == EINTR)
                nwritten = 0;
            else
                return(-1);
        }
        nleft -= nwritten;
        ptr += nwritten;
    }
    return(n);
}

bool 
Writen(int fd,const void *vptr, size_t nbytes)
{
    return (writen(fd, vptr, nbytes) != nbytes);
}

ssize_t 
readline(int fd, void *vptr, size_t maxlen)
{
     int n, rc;
     char c, *ptr;
     ptr = (char*)vptr;
     for (n = 1; n < maxlen; n++) 
     {
           if (rc = Readn(fd,&c,1) == 1) 
           {
                 *ptr++ = c;
                 if (c == '\n')
                      break;
           }
           else if (rc == 0) 
           {
                 if (n == 1)
                      return(0);
                 else
                      break;
           } 
           else
               return(-1);
     }
     *ptr = 0;
     return(n);
}

ssize_t 
Readline(int fd, void *ptr, size_t maxlen)
{
     ssize_t n;
     if ((n = readline(fd, ptr, maxlen)) < 0)
     {
         err_sys("readline error");
         return -1;
     }
     return(n);
}

ssize_t 
my_read(int fd, char *ptr)
{
    int   read_cnt = 0;
    char  *read_ptr;
    char  read_buf[MAXLINE];
    if (read_cnt <= 0) 
    {
        again:
        if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) 
        {
             if (errno == EINTR)
                 goto again;
             return(-1);
        } 
        else if (read_cnt == 0)
             return(0);
        
        read_ptr = read_buf;
    }
    read_cnt--;
    *ptr = *read_ptr++;
    return(1);
}


int 
Socket(int domain,int type,int protocol)
{
    int val;
    
    if((val = socket(domain,type,protocol)) < 0)
    {
        err_sys("error creating socket");
        return -1;
    }
    return val;
}

bool 
Close(int fd)
{
    int val;
    if((val = close(fd)) < 0)
    {
        return err_sys("error closing socket");
    }
    
    return true;   
}


int
Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)
{
	int		n;

again:
	if ( (n = accept(fd, sa, salenptr)) < 0) {
#ifdef	EPROTO
		if (errno == EPROTO || errno == ECONNABORTED)
#else
		if (errno == ECONNABORTED)
#endif
			goto again;
		else
                {
                    err_sys("error accepting");
                    return -1;
                }
                
	}
	return(n);
}

bool
Bind(int fd, const struct sockaddr *sa, socklen_t salen)
{
	if (bind(fd, sa, salen) < 0)
		return err_sys("bind error");
        return true;
}

bool
Connect(int fd, const struct sockaddr *sa, socklen_t salen)
{
	if (connect(fd, sa, salen) < 0)
		return err_sys("connect error");
        return true;
}

bool
Getpeername(int fd, struct sockaddr *sa, socklen_t *salenptr)
{
	if (getpeername(fd, sa, salenptr) < 0)
		return err_sys("getpeername error");
        return true;
}

bool
Getsockname(int fd, struct sockaddr *sa, socklen_t *salenptr)
{
	if (getsockname(fd, sa, salenptr) < 0)
		return err_sys("getsockname error");
        return true;
}

bool
Getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlenptr)
{
	if (getsockopt(fd, level, optname, optval, optlenptr) < 0)
		return err_sys("getsockopt error");
        return true;
}

int
Isfdtype(int fd, int fdtype)
{
	int		n;

	if ( (n = isfdtype(fd, fdtype)) < 0)
		err_sys("isfdtype error");
	return(n);
}

/* include Listen */
bool
Listen(int fd, int backlog)
{
	char	*ptr;

		/*4can override 2nd argument with environment variable */
	if ( (ptr = (char *) getenv("LISTENQ")) != NULL)
		backlog = atoi(ptr);

	if (listen(fd, backlog) < 0)
            return false;
        return true;
}

const char *
Inet_ntop(int family, const void *addrptr, char *strptr, size_t len)
{
	const char	*ptr;

	if (strptr == NULL)		/* check for old code */
        {
            err_sys("NULL 3rd argument to inet_ntop");
            return NULL;
        }
        
	if ( (ptr = inet_ntop(family, addrptr, strptr, len)) == NULL)
        {
            err_sys("inet_ntop error");		/* sets errno */
            return NULL;
        }
	
	return(ptr);
}

bool
Inet_pton(int family, const char *strptr, void *addrptr)
{
	int		n;

	if ( (n = inet_pton(family, strptr, addrptr)) <= 0)
		return err_sys("inet_pton error");	/* errno set */
	
        return true;
	/* nothing to return */
}

int	inet_host2addr (char *host, struct in_addr *address)
{	
	/* Number is is in internet address dot notation */
	if ( isdigit(*host) )
	{	
		//address->s_addr = inet_addr(host);
          //  inet_pton(AF_INET,host,&address->s_addr);
            inet_aton(host,address);
	}
	/* hostname.domainname form */
	else
	{	
		struct hostent *HostData;

		HostData = gethostbyname(host);
		if ( HostData == NULL )
			return -1;
		*address = *((struct in_addr *) HostData->h_addr);
	}

	return 0;			/* No error */
}


/*
 * pthreads wrapper functions.
 */

bool 
Pthread_create(pthread_t *tid, const pthread_attr_t *attr,
			   void * (*func)(void *), void *arg)
{
	int		n;

	if ( (n = pthread_create(tid, attr, func, arg)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_create error");
}

bool
Pthread_join(pthread_t tid, void **status)
{
	int		n;

	if ( (n = pthread_join(tid, status)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_join error");
}

bool
Pthread_detach(pthread_t tid)
{
	int		n;

	if ( (n = pthread_detach(tid)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_detach error");
}

bool
Pthread_kill(pthread_t tid, int signo)
{
	int n;

	if ( (n = pthread_kill(tid, signo)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_kill error");
}

bool
Pthread_cancel(pthread_t tid)
{
	int n;

	if ( (n = pthread_cancel(tid)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_cancel error");
}
bool
Pthread_mutexattr_init(pthread_mutexattr_t *attr)
{
	int		n;

	if ( (n = pthread_mutexattr_init(attr)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_mutexattr_init error");
}

#ifdef	_POSIX_THREAD_PROCESS_SHARED
bool
Pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int flag)
{
	int		n;

	if ( (n = pthread_mutexattr_setpshared(attr, flag)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_mutexattr_setpshared error");
}
#endif

bool
Pthread_mutex_init(pthread_mutex_t *mptr, pthread_mutexattr_t *attr)
{
	int		n;

	if ( (n = pthread_mutex_init(mptr, attr)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_mutex_init error");
}

/* include Pthread_mutex_lock */
bool
Pthread_mutex_lock(pthread_mutex_t *mptr)
{
	int		n;

	if ( (n = pthread_mutex_lock(mptr)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_mutex_lock error");
}
/* end Pthread_mutex_lock */

bool
Pthread_mutex_unlock(pthread_mutex_t *mptr)
{
	int		n;

	if ( (n = pthread_mutex_unlock(mptr)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_mutex_unlock error");
}

bool
Pthread_cond_broadcast(pthread_cond_t *cptr)
{
	int		n;

	if ( (n = pthread_cond_broadcast(cptr)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_cond_broadcast error");
}

bool
Pthread_cond_signal(pthread_cond_t *cptr)
{
	int		n;

	if ( (n = pthread_cond_signal(cptr)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_cond_signal error");
}

bool
Pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr)
{
	int		n;

	if ( (n = pthread_cond_wait(cptr, mptr)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_cond_wait error");
}

bool
Pthread_cond_timedwait(pthread_cond_t *cptr, pthread_mutex_t *mptr,
					   const struct timespec *tsptr)
{
	int		n;

	if ( (n = pthread_cond_timedwait(cptr, mptr, tsptr)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_cond_timedwait error");
}

bool
Pthread_once(pthread_once_t *ptr, void (*func)(void))
{
	int		n;

	if ( (n = pthread_once(ptr, func)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_once error");
}

bool
Pthread_key_create(pthread_key_t *key, void (*func)(void *))
{
	int		n;

	if ( (n = pthread_key_create(key, func)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_key_create error");
}

bool
Pthread_setspecific(pthread_key_t key, const void *value)
{
	int		n;

	if ( (n = pthread_setspecific(key, value)) == 0)
		return true;
	errno = n;
	return err_sys("pthread_setspecific error");
}


#endif	/* _COMMON_H */

